﻿/* ============================================================================
(c) Copyright 2012 Hewlett-Packard Development Company, L.P.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge,publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
============================================================================ */
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
using System.Net.Http;

namespace HPCloud.Objects.Domain
{
    public enum StorageObjectType
    {
        Folder = 0,
        File   = 1
    }
    
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.1")]
    [System.Xml.Serialization.XmlTypeAttribute("object")]
        
    public class StorageObject
    {
        private string _etag;
        private string _key;
        private string _storageClass;
        private string _lastModified;
        private long _size;
        private HttpContent _content;
        private string _versionId;
        private bool _isDeleted = false;
        private string _server;
        private DateTime _responseDate;
        private string _objectType = "File";
        private List<KeyValuePair<string, string>> _extendedProperties = new List<KeyValuePair<string, string>>();
        private string _fileName;
        private string _FQLocalPath;
        private string _contentType;
        private StorageObjectType _storageObjectType;

        #region Properties
//================================================================================
/// <summary>
/// </summary>
//================================================================================
        public string FQLocalPath
        {
            get { return _FQLocalPath; }
            set { _FQLocalPath = value; }
        }
//================================================================================
/// <summary>
/// </summary>
//================================================================================
        [XmlElement("name")]
        public string FileName
        {
            get { return _fileName; }
            set { _fileName = value; }
        }
//================================================================================
/// <summary>
/// </summary>
//================================================================================
        [XmlIgnore]
        public List<KeyValuePair<string, string>> ExtendedProperties
        {
            get { return _extendedProperties; }
            set { _extendedProperties = value; }
        }
//================================================================================
/// <summary>
/// </summary>
//================================================================================
        [System.Xml.Serialization.XmlElementAttribute("name")]
        public string DisplayName
        {
            get 
            {
                if (Path.GetFileName(this.Key) == "folder.txt")
                {
                    return Path.GetDirectoryName(this.Key);
                }
                else
                {
                    return Path.GetFileName(this.Key);
                }
            }
        }
//================================================================================
/// <summary>
/// </summary>
//================================================================================
        [System.Xml.Serialization.XmlElementAttribute("content_type")]
        public string ContentType
        {
            set
            {
                _contentType = value;
                if (value == "application/directory")
                {
                    this.StorageObjectType = Domain.StorageObjectType.Folder;
                    this.ObjectType        = "Folder";
                }
                else
                {
                    this.StorageObjectType = Domain.StorageObjectType.File;
                }
            }
            get
            {
                return _contentType;
            }
        } 
//================================================================================
/// <summary>
/// </summary>
//================================================================================
        public string ObjectType
        {
            set
            {
                _objectType = value;
            }
            get 
            {
                if (_contentType == "application/directory")
                {
                    return "Folder";
                }
                else
                {
                    return "File";
                }
            }
        }
//================================================================================
/// <summary>
/// 
/// </summary>
//================================================================================
        public StorageObjectType StorageObjectType
        {
            get
            {
                return _storageObjectType;
            }
            set
            {
                _storageObjectType = value;

                if (value == Domain.StorageObjectType.Folder)
                {
                    _contentType = "application/directory";
                }
            }
        }
//================================================================================
/// <summary>
/// The date and time HPKVS responded, for example, Wed, 01 Mar 2009
///12:00:00 GMT. (TODO-nitin: format examples distinctly from text.)
///Type: String
/// </summary>
//================================================================================
        public DateTime ResponseDate
        {
            get { return _responseDate; }
            set { _responseDate = value; }
        }
//================================================================================
/// <summary>
/// The name of the server that created the response.
/// </summary>
//================================================================================
        public string Server
        {
            get { return _server; }
            set { _server = value; }
        }
//================================================================================
/// <summary>
/// 
/// </summary>
//================================================================================
        public bool IsDeleted
        {
            get { return _isDeleted; }
            set { _isDeleted = value; }
        }
//================================================================================
/// <summary>
/// 
/// </summary>
//================================================================================
        public string VersionId
        {
            get { return _versionId; }
            set { _versionId = value; }
        }
//================================================================================
/// <summary>
/// 
/// </summary>
//================================================================================
        [System.Xml.Serialization.XmlElementAttribute("bytes")]
        public long Size
        {
            get { return _size; }
            set { _size = value; }
        }
//================================================================================
/// <summary>
/// 
/// </summary>
//================================================================================
        [System.Xml.Serialization.XmlElementAttribute("last_modified")] 
        public string LastModified
        {
            get { return _lastModified; }
            set { _lastModified = value; }
        }
//================================================================================
/// <summary>
/// 
/// </summary>
//================================================================================
        [System.Xml.Serialization.XmlElementAttribute("StorageClass")]
        public string StorageClass
        {
            get { return _storageClass; }
            set { _storageClass = value; }
        }
//================================================================================
/// <summary>
/// 
/// </summary>
//================================================================================
        [System.Xml.Serialization.XmlElementAttribute("hash")]
        public string ETag
        {
            get { return _etag; }
            set { _etag = value; }
        }
//================================================================================
/// <summary>
/// 
/// </summary>
//================================================================================
        public string Key
        {
            get
            {
                if (_key != null)
                {
                    if (_key.StartsWith("/"))
                    {
                        return _key.Substring(1).Replace(@"//", @"/");
                    }
                    else
                    {
                        return _key.Replace(@"//", @"/");
                    }
                }
                else
                {
                    return _fileName;
                }
            }
            set
            {
                _key = value;

            }
        }
        #endregion
        #region Methods
//================================================================================
/// <summary>
/// 
/// </summary>
/// <param name="content"></param>
//================================================================================
        public void LoadFile(StoragePath path)
        {
            FileStream stream = null;

            if (!path.Volume.EndsWith(@"\") && !path.Path.StartsWith(@"\"))
            {
                stream = new FileStream(path.Volume + @"\" + path.Path, FileMode.Open);
            }
            else
            {
                stream = new FileStream(path.Volume + path.Path, FileMode.Open);
            }

            _content          = new StreamContent(stream);
            _fileName         = Path.GetFileName(path.ResourcePath);
            _FQLocalPath      = path.Path;
            _size             = stream.Length;
        }
//================================================================================
/// <summary>
/// 
/// </summary>
/// <param name="content"></param>
//================================================================================
        public void LoadFile(string path)
        {
            FileStream stream = new FileStream(path, FileMode.Open);
            _content          = new StreamContent(stream);
            _fileName         = Path.GetFileName(path);
            _FQLocalPath      = path;
            _size             = stream.Length;
        }
//================================================================================
/// <summary>
/// 
/// </summary>
/// <returns></returns>
//================================================================================
        public Stream ToStream()
        {
            return _content.ReadAsStreamAsync().Result;
        }
//================================================================================
/// <summary>
/// 
/// </summary>
/// <param name="content"></param>
//================================================================================
        public void Load (string content)
        {
            _content = new StringContent(content, System.Text.Encoding.UTF8, "text/plain");
        }
//================================================================================
/// <summary>
/// 
/// </summary>
/// <param name="content"></param>
//================================================================================
        public void Load(Stream stream)
        {          
            _content = new StreamContent(stream);
            _size = Convert.ToInt32(_content.Headers.ContentLength);
        }
//================================================================================
/// <summary>       
/// </summary>
/// <param name="content"></param>
//================================================================================
        public void Load(byte[] buffer)
        {
            MemoryStream stream = new MemoryStream(buffer);
            _content            = new StreamContent(stream);
            _size               = Convert.ToInt32(_content.Headers.ContentLength);
        }
        #endregion
        #region Methods
//================================================================================
/// <summary>
/// 
/// </summary>
/// <returns></returns>
//================================================================================
        public void Save(Stream stream)
        {
            if (_content != null)
            {
                _content.CopyToAsync(stream).ContinueWith( 
                                            (copyTask) => 
                                            {
                                                stream.Close(); 
                                            }); 
            }
            else
            {
                FileStream fileStream = stream as FileStream;

                if (fileStream != null)
                {
                    fileStream.Close();
                }
            }
        }
//================================================================================
/// <summary>
/// 
/// </summary>
/// <returns></returns>
//================================================================================
        public HttpContent ToHttpContent()
        {
            return _content;
        }
//================================================================================
/// <summary>
/// 
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
//================================================================================
        private string GetMimeType(string fileName)
        {
            string mimeType = "application/unknown";
            string ext      = System.IO.Path.GetExtension(fileName).ToLower();

            Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);

            if (regKey != null && regKey.GetValue("Content Type") != null)
            {
                mimeType = regKey.GetValue("Content Type").ToString();
            }
            return mimeType;
        }
        #endregion
    }
}
